<template><div><h2 id="使用数据库" tabindex="-1"><a class="header-anchor" href="#使用数据库"><span>使用数据库</span></a></h2>
<p>本章节将介绍如何创建一个从数据表 <code v-pre>country</code> 中读取国家数据并显示出来的页面。 为了实现这个目标，你将会配置一个数据库连接， 创建一个<a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/db-active-record.md" target="_blank" rel="noopener noreferrer">活动记录</a>类， 并且创建一个<a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/structure-controllers.md" target="_blank" rel="noopener noreferrer">操作</a>及一个<a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/structure-views.md" target="_blank" rel="noopener noreferrer">视图</a>。</p>
<p>贯穿整个章节，你将会学到：</p>
<ul>
<li>配置一个数据库连接</li>
<li>定义一个活动记录类</li>
<li>使用活动记录从数据库中查询数据</li>
<li>以分页方式在视图中显示数据</li>
</ul>
<p>请注意，为了掌握本章你应该具备最基本的数据库知识和使用经验。 尤其是应该知道如何创建数据库，如何通过数据库终端执行 SQL 语句。</p>
<h2 id="准备数据库" tabindex="-1"><a class="header-anchor" href="#准备数据库"><span>准备数据库</span></a></h2>
<p>首先创建一个名为 <code v-pre>yii2basic</code> 的数据库，应用将从这个数据库中读取数据。 你可以创建 SQLite，MySQL，PostregSQL，MSSQL 或 Oracle 数据库，Yii 内置多种数据库支持。简单起见，后面的内容将以 MySQL 为例做演示。</p>
<blockquote>
<p>Info: 虽然 MariaDB 曾经是 MySQL 的直接替代品，但现在已经不再完全正确。如果您希望在 MariaDB 中使用“JSON”支持等高级功能，请查看下面列出的 MariaDB 扩展。</p>
</blockquote>
<p>然后在数据库中创建一个名为 <code v-pre>country</code> 的表并插入简单的数据。可以执行下面的语句：</p>
<div class="language-sql line-numbers-mode" data-highlighter="prismjs" data-ext="sql" data-title="sql"><pre v-pre class="language-sql"><code><span class="line"><span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> <span class="token identifier"><span class="token punctuation">`</span>country<span class="token punctuation">`</span></span> <span class="token punctuation">(</span></span>
<span class="line">  <span class="token identifier"><span class="token punctuation">`</span>code<span class="token punctuation">`</span></span> <span class="token keyword">CHAR</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">PRIMARY</span> <span class="token keyword">KEY</span><span class="token punctuation">,</span></span>
<span class="line">  <span class="token identifier"><span class="token punctuation">`</span>name<span class="token punctuation">`</span></span> <span class="token keyword">CHAR</span><span class="token punctuation">(</span><span class="token number">52</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span></span>
<span class="line">  <span class="token identifier"><span class="token punctuation">`</span>population<span class="token punctuation">`</span></span> <span class="token keyword">INT</span><span class="token punctuation">(</span><span class="token number">11</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">DEFAULT</span> <span class="token string">'0'</span></span>
<span class="line"><span class="token punctuation">)</span> <span class="token keyword">ENGINE</span><span class="token operator">=</span><span class="token keyword">InnoDB</span> <span class="token keyword">DEFAULT</span> <span class="token keyword">CHARSET</span><span class="token operator">=</span>utf8<span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token identifier"><span class="token punctuation">`</span>country<span class="token punctuation">`</span></span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'AU'</span><span class="token punctuation">,</span><span class="token string">'Australia'</span><span class="token punctuation">,</span><span class="token number">18886000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token identifier"><span class="token punctuation">`</span>country<span class="token punctuation">`</span></span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'BR'</span><span class="token punctuation">,</span><span class="token string">'Brazil'</span><span class="token punctuation">,</span><span class="token number">170115000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token identifier"><span class="token punctuation">`</span>country<span class="token punctuation">`</span></span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'CA'</span><span class="token punctuation">,</span><span class="token string">'Canada'</span><span class="token punctuation">,</span><span class="token number">1147000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token identifier"><span class="token punctuation">`</span>country<span class="token punctuation">`</span></span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'CN'</span><span class="token punctuation">,</span><span class="token string">'China'</span><span class="token punctuation">,</span><span class="token number">1277558000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token identifier"><span class="token punctuation">`</span>country<span class="token punctuation">`</span></span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'DE'</span><span class="token punctuation">,</span><span class="token string">'Germany'</span><span class="token punctuation">,</span><span class="token number">82164700</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token identifier"><span class="token punctuation">`</span>country<span class="token punctuation">`</span></span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'FR'</span><span class="token punctuation">,</span><span class="token string">'France'</span><span class="token punctuation">,</span><span class="token number">59225700</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token identifier"><span class="token punctuation">`</span>country<span class="token punctuation">`</span></span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'GB'</span><span class="token punctuation">,</span><span class="token string">'United Kingdom'</span><span class="token punctuation">,</span><span class="token number">59623400</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token identifier"><span class="token punctuation">`</span>country<span class="token punctuation">`</span></span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'IN'</span><span class="token punctuation">,</span><span class="token string">'India'</span><span class="token punctuation">,</span><span class="token number">1013662000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token identifier"><span class="token punctuation">`</span>country<span class="token punctuation">`</span></span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'RU'</span><span class="token punctuation">,</span><span class="token string">'Russia'</span><span class="token punctuation">,</span><span class="token number">146934000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token identifier"><span class="token punctuation">`</span>country<span class="token punctuation">`</span></span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'US'</span><span class="token punctuation">,</span><span class="token string">'United States'</span><span class="token punctuation">,</span><span class="token number">278357000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>此时便有了一个名为 <code v-pre>yii2basic</code> 的数据库，在这个数据库中有一个包含三个字段的数据表 <code v-pre>country</code>，表中有十行数据。</p>
<h2 id="配置数据库连接" tabindex="-1"><a class="header-anchor" href="#配置数据库连接"><span>配置数据库连接</span></a></h2>
<p>开始之前，请确保你已经安装了 PHP <a href="https://www.php.net/manual/en/book.pdo.php" target="_blank" rel="noopener noreferrer">PDO</a> 扩展和你所使用的数据库的 PDO 驱动（例如 MySQL 的 <code v-pre>pdo_mysql</code>）。 对于使用关系型数据库来讲，这是基本要求。</p>
<p>驱动和扩展安装可用后，打开 <code v-pre>config/db.php</code> 修改里面的配置参数对应你的数据库配置。 该文件默认包含这些内容：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">return</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'class'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'yii\db\Connection'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'dsn'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'mysql:host=localhost;dbname=yii2basic'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'username'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'root'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'password'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">''</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'charset'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'utf8'</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code v-pre>config/db.php</code> 是一个典型的基于文件的<a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/concept-configurations.md" target="_blank" rel="noopener noreferrer">配置</a>工具。 这个文件配置了数据库连接 [[yii\db\Connection]] 的创建和初始化参数， 应用的 SQL 查询正是基于这个数据库。</p>
<p>上面配置的数据库连接可以在应用中通过 <code v-pre>Yii::$app-&gt;db</code> 表达式访问。</p>
<blockquote>
<p>Info: <code v-pre>config/db.php</code> 将被包含在应用配置文件 <code v-pre>config/web.php</code> 中， 后者指定了整个<a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/structure-applications.md" target="_blank" rel="noopener noreferrer">应用</a>如何初始化。 请参考<a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/concept-configurations.md" target="_blank" rel="noopener noreferrer">配置</a>章节了解更多信息。</p>
</blockquote>
<p>如果想要使用 Yii 没有捆绑支持的数据库，你可以查看以下插件：</p>
<ul>
<li><a href="https://github.com/edgardmessias/yii2-informix" target="_blank" rel="noopener noreferrer">Informix</a></li>
<li><a href="https://github.com/edgardmessias/yii2-ibm-db2" target="_blank" rel="noopener noreferrer">IBM DB2</a></li>
<li><a href="https://github.com/edgardmessias/yii2-firebird" target="_blank" rel="noopener noreferrer">Firebird</a></li>
<li><a href="https://github.com/sam-it/yii2-mariadb" target="_blank" rel="noopener noreferrer">MariaDB</a></li>
</ul>
<h2 id="创建活动记录" tabindex="-1"><a class="header-anchor" href="#创建活动记录"><span>创建活动记录</span></a></h2>
<p>创建一个继承自<a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/db-active-record.md" target="_blank" rel="noopener noreferrer">活动记录</a>类的类 <code v-pre>Country</code>， 把它放在 <code v-pre>models/Country.php</code> 文件，去代表和读取 <code v-pre>country</code> 表的数据。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">app<span class="token punctuation">\</span>models</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>db<span class="token punctuation">\</span>ActiveRecord</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">Country</span> <span class="token keyword">extends</span> <span class="token class-name">ActiveRecord</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这个 <code v-pre>Country</code> 类继承自 [[yii\db\ActiveRecord]]。你不用在里面写任何代码。 只需要像现在这样，Yii 就能根据类名去猜测对应的数据表名。</p>
<blockquote>
<p>Info: 如果类名和数据表名不能直接对应， 可以覆写 [[yii\db\ActiveRecord::tableName()|tableName()]] 方法去显式指定相关表名。</p>
</blockquote>
<p>使用 <code v-pre>Country</code> 类可以很容易地操作 <code v-pre>country</code> 表数据，就像这段代码：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">app<span class="token punctuation">\</span>models<span class="token punctuation">\</span>Country</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 获取 country 表的所有行并以 name 排序</span></span>
<span class="line"><span class="token variable">$countries</span> <span class="token operator">=</span> <span class="token class-name static-context">Country</span><span class="token operator">::</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">orderBy</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'name'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 获取主键为 “US” 的行</span></span>
<span class="line"><span class="token variable">$country</span> <span class="token operator">=</span> <span class="token class-name static-context">Country</span><span class="token operator">::</span><span class="token function">findOne</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'US'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 输出 “United States”</span></span>
<span class="line"><span class="token keyword">echo</span> <span class="token variable">$country</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 修改 name 为 “U.S.A.” 并在数据库中保存更改</span></span>
<span class="line"><span class="token variable">$country</span><span class="token operator">-></span><span class="token property">name</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'U.S.A.'</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$country</span><span class="token operator">-></span><span class="token function">save</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>Info: 活动记录是面向对象、功能强大的访问和操作数据库数据的方式。你可以在<a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/db-active-record.md" target="_blank" rel="noopener noreferrer">活动记录</a>章节了解更多信息。 除此之外你还可以使用另一种更原生的被称做<a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/db-dao" target="_blank" rel="noopener noreferrer">数据访问对象</a>的方法操作数据库数据。</p>
</blockquote>
<h2 id="创建动作" tabindex="-1"><a class="header-anchor" href="#创建动作"><span>创建动作</span></a></h2>
<p>为了向最终用户显示国家数据，你需要创建一个操作。相比之前小节掌握的在 <code v-pre>site</code> 控制器中创建操作， 在这里为所有和国家有关的数据新建一个控制器更加合理。 新控制器名为 <code v-pre>CountryController</code>，并在其中创建一个 <code v-pre>index</code> 操作， 如下：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">app<span class="token punctuation">\</span>controllers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>web<span class="token punctuation">\</span>Controller</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>data<span class="token punctuation">\</span>Pagination</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">app<span class="token punctuation">\</span>models<span class="token punctuation">\</span>Country</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">CountryController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">actionIndex</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$query</span> <span class="token operator">=</span> <span class="token class-name static-context">Country</span><span class="token operator">::</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token variable">$pagination</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Pagination</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'defaultPageSize'</span> <span class="token operator">=></span> <span class="token number">5</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'totalCount'</span> <span class="token operator">=></span> <span class="token variable">$query</span><span class="token operator">-></span><span class="token function">count</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token variable">$countries</span> <span class="token operator">=</span> <span class="token variable">$query</span><span class="token operator">-></span><span class="token function">orderBy</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'name'</span><span class="token punctuation">)</span></span>
<span class="line">            <span class="token operator">-></span><span class="token function">offset</span><span class="token punctuation">(</span><span class="token variable">$pagination</span><span class="token operator">-></span><span class="token property">offset</span><span class="token punctuation">)</span></span>
<span class="line">            <span class="token operator">-></span><span class="token function">limit</span><span class="token punctuation">(</span><span class="token variable">$pagination</span><span class="token operator">-></span><span class="token property">limit</span><span class="token punctuation">)</span></span>
<span class="line">            <span class="token operator">-></span><span class="token function">all</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token keyword">return</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">render</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'index'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'countries'</span> <span class="token operator">=></span> <span class="token variable">$countries</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'pagination'</span> <span class="token operator">=></span> <span class="token variable">$pagination</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>把上面的代码保存在 <code v-pre>controllers/CountryController.php</code> 文件中。</p>
<p><code v-pre>index</code> 操作调用了活动记录 <code v-pre>Country::find()</code> 方法，去生成查询语句并从 <code v-pre>country</code> 表中取回所有数据。 为了限定每个请求所返回的国家数量，查询在 [[yii\data\Pagination]] 对象的帮助下进行分页。 <code v-pre>Pagination</code> 对象的使命主要有两点：</p>
<ul>
<li>为 SQL 查询语句设置 <code v-pre>offset</code> 和 <code v-pre>limit</code> 从句， 确保每个请求只需返回一页数据（本例中每页是 5 行）。</li>
<li>在视图中显示一个由页码列表组成的分页器， 这点将在后面的段落中解释。</li>
</ul>
<p>在代码末尾，<code v-pre>index</code> 操作渲染一个名为 <code v-pre>index</code> 的视图， 并传递国家数据和分页信息进去。</p>
<h2 id="创建视图" tabindex="-1"><a class="header-anchor" href="#创建视图"><span>创建视图</span></a></h2>
<p>在 <code v-pre>views</code> 目录下先创建一个名为 <code v-pre>country</code> 的子目录。 这个目录存储所有由 <code v-pre>country</code> 控制器渲染的视图。在 <code v-pre>views/country</code> 目录下 创建一个名为 <code v-pre>index.php</code> 的视图文件，内容如下：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>helpers<span class="token punctuation">\</span>Html</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>widgets<span class="token punctuation">\</span>LinkPager</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token delimiter important">?></span></span></span>
<span class="line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>Countries<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span></span>
<span class="line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span></span>
<span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$countries</span> <span class="token keyword">as</span> <span class="token variable">$country</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token delimiter important">?></span></span></span>
<span class="line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span></span>
<span class="line">        <span class="token php language-php"><span class="token delimiter important">&lt;?=</span> <span class="token class-name static-context">Html</span><span class="token operator">::</span><span class="token function">encode</span><span class="token punctuation">(</span><span class="token string double-quoted-string">"<span class="token interpolation"><span class="token punctuation">{</span><span class="token variable">$country</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">}</span></span> (<span class="token interpolation"><span class="token punctuation">{</span><span class="token variable">$country</span><span class="token operator">-></span><span class="token property">code</span><span class="token punctuation">}</span></span>)"</span><span class="token punctuation">)</span> <span class="token delimiter important">?></span></span>:</span>
<span class="line">        <span class="token php language-php"><span class="token delimiter important">&lt;?=</span> <span class="token variable">$country</span><span class="token operator">-></span><span class="token property">population</span> <span class="token delimiter important">?></span></span></span>
<span class="line">    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span></span>
<span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span> <span class="token keyword">endforeach</span><span class="token punctuation">;</span> <span class="token delimiter important">?></span></span></span>
<span class="line"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span></span>
<span class="line"></span>
<span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?=</span> <span class="token class-name static-context">LinkPager</span><span class="token operator">::</span><span class="token function">widget</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'pagination'</span> <span class="token operator">=></span> <span class="token variable">$pagination</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token delimiter important">?></span></span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这个视图包含两部分用以显示国家数据。第一部分遍历国家数据并以无序 HTML 列表渲染出来。 第二部分使用 [[yii\widgets\LinkPager]] 去渲染从操作中传来的分页信息。 小部件 <code v-pre>LinkPager</code> 显示一个分页按钮的列表。 点击任何一个按钮都会跳转到对应的分页。</p>
<h2 id="试运行" tabindex="-1"><a class="header-anchor" href="#试运行"><span>试运行</span></a></h2>
<p>浏览器访问下面的 URL 看看能否工作：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">http://hostname/index.php?r<span class="token operator">=</span>country/index</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p><a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/images/start-country-list.png" target="_blank" rel="noopener noreferrer"><img src="https://github.com/yiisoft/yii2/raw/master/docs/guide-zh-CN/images/start-country-list.png" alt="国家列表"></a></p>
<p>首先你会看到显示着五个国家的列表页面。在国家下面，你还会看到一个包含四个按钮的分页器。 如果你点击按钮 “2”，将会跳转到显示另外五个国家的页面， 也就是第二页记录。如果观察仔细点你还会看到浏览器的 URL 变成了：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">http://hostname/index.php?r<span class="token operator">=</span>country/index<span class="token operator">&amp;</span><span class="token assign-left variable">page</span><span class="token operator">=</span><span class="token number">2</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>在这个场景里，[[yii\data\Pagination|Pagination]] 提供了为数据结果集分页的所有功能：</p>
<ul>
<li>首先 [[yii\data\Pagination|Pagination]] 把 SELECT 的子查询 <code v-pre>LIMIT 5 OFFSET 0</code> 数据表示成第一页。 因此开头的五条数据会被取出并显示。</li>
<li>然后小部件 [[yii\widgets\LinkPager|LinkPager]] 使用 [[yii\data\Pagination::createUrl()|Pagination::createUrl()]] 方法生成的 URL 去渲染翻页按钮。 URL 中包含必要的参数 <code v-pre>page</code> 才能查询不同的页面编号。</li>
<li>如果你点击按钮 “2”，将会发起一个路由为 <code v-pre>country/index</code> 的新请求。 [[yii\data\Pagination|Pagination]] 接收到 URL 中 的 <code v-pre>page</code> 参数把当前的页码设为 2。 新的数据库请求将会以 <code v-pre>LIMIT 5 OFFSET 5</code> 查询并显示。</li>
</ul>
<h2 id="总结" tabindex="-1"><a class="header-anchor" href="#总结"><span>总结</span></a></h2>
<p>本章节中你学到了如何使用数据库。你还学到了如何取出并使用 [[yii\data\Pagination]] 和 [[yii\widgets\LinkPager]] 显示数据。</p>
<p>下一章中你会学到如何使用 Yii 中强大的代码生成器 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/tool-gii.md" target="_blank" rel="noopener noreferrer">Gii</a>， 去帮助你实现一些常用的功能需求， 例如增查改删（CRUD）数据表中的数据。 事实上你之前所写的代码全部都可以由 Gii 自动生成。</p>
<blockquote>
<p>💖喜欢本文档的，欢迎点赞、收藏、留言或转发，谢谢支持！<br>
作者邮箱：zhuzixian520@126.com，github地址：<a href="https://github.com/zhuzixian520" target="_blank" rel="noopener noreferrer">github.com/zhuzixian520</a></p>
</blockquote>
</div></template>


